﻿using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;

namespace LoggingSimpleDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            #region 从文件中读取配置的一个过程
            IConfigurationBuilder configurationBuilder = new ConfigurationBuilder();

            //添加命令行
            configurationBuilder.AddCommandLine(args);

            configurationBuilder.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
            var config = configurationBuilder.Build();
            #endregion

            IServiceCollection serviceCollection = new ServiceCollection();
            serviceCollection.AddSingleton<IConfiguration>(p => config);//用工厂模式将配置对象注册到容器中管理
            serviceCollection.AddLogging(builder =>
            {
                //一行代码是把我们的Logging的配置Section注册进去 
                builder.AddConfiguration(config.GetSection("Logging"));
                //一行代码是添加一个Console，也就是我们先使用了一个Console的日志输出，
                builder.AddConsole();

                //在日志显示的时候让他输出在vsdebug窗口中
                builder.AddDebug();
            });
            IServiceProvider service = serviceCollection.BuildServiceProvider();

            var logger = service.GetService<ILogger<Program>>();

            while (Console.ReadKey().Key!=ConsoleKey.Escape)
            {
                //创建日志Scope,相当于我们记录了一条上下文串联的日志
                using (logger.BeginScope("ScopedId:{scopedId}", Guid.NewGuid()))
                {
                    logger.LogInformation("这是info");
                    logger.LogError("这是Err");
                    logger.LogTrace("这是Trace");
                }
                System.Threading.Thread.Sleep(100);
                Console.WriteLine("===========分割线===========");
            }
           

            Console.ReadKey();


            #region 上一节
            ////构造一个容器
            //IServiceCollection serviceCollection = new ServiceCollection();
            ////将我们的配置用工厂的模式注入到我们的配置中。这有个小技巧，我们在注册我们的实例的时候，可以用工厂的模式，这里我们注入的时候用了一个委托，那就意味着我们的容器是可以帮我们来管理这个对象的生命周期的。如果我们serviceCollection.AddSingleton<IConfiguration>(config);这样将容器直接注入进去，那么容器是不会帮我们管理Configuration的生命周期的，所以我们这里用一个委托注入的方式，就是工厂模式注入。
            //serviceCollection.AddSingleton<IConfiguration>(p => config);//用工厂模式将配置对象注册到容器中管理

            ////看一下源码，AddLogging往我们的容器中注册了几个关键的对象，一个ILoggerFactory、一个ILogger的泛型模板，还有一个是IConfigurationOptions<LoggerFilterOptions>（logger的过滤的配置）。configure就是我们整个注入的委托。 这里面他new了一个LoggingBuilder，这个LoggingBuilder是一个非常简单的类， 他只有一个属性就是IServiceCollection，这个services本质上就是我刚才创建的容器的对象。
            ////我们也可以看到我们在委托里面执行注入了两行代码，
            //serviceCollection.AddLogging(builder =>
            //{
            //    //一行代码是把我们的Logging的配置Section注册进去 
            //    builder.AddConfiguration(config.GetSection("Logging"));
            //    //一行代码是添加一个Console，也就是我们先使用了一个Console的日志输出，
            //    builder.AddConsole();

            //    //在日志显示的时候让他输出在vsdebug窗口中
            //    builder.AddDebug();
            //});


            ////注入我们的服务OrderService
            //serviceCollection.AddTransient<OrderService>();

            ////这里用serviceCollection build了一个ServiceProvider，也就是把我们的容器Build出来，我们就可以借助这个ServiceProvider 
            //IServiceProvider service = serviceCollection.BuildServiceProvider();


            //var order = service.GetService<OrderService>();
            //order.Show();


            //////从容器中获取ILoggerFactory 
            //////查看ILoggerFactory，他的作用就是让我们获取我们的日志记录器，他只有两个方法，ILogger CreateLogger(String categoryName)和void AddProvider(ILoggerProvider provider )
            ////ILoggerFactory loggerFactory = service.GetService<ILoggerFactory>();

            //////创建日志记录器,获取一个ILogger对象，这个对象的名字叫做alogger
            ////ILogger alogger = loggerFactory.CreateLogger("alogger");

            ////alogger.LogDebug(2001, "aiya");
            ////alogger.LogInformation("info");
            ////alogger.LogWarning("warning");
            ////var ex = new Exception("出错了");
            ////alogger.LogError(ex,"error");

            ////var alogger2 = loggerFactory.CreateLogger("alogger");

            ////alogger2.LogDebug("aiya"); 
            #endregion

        }
    }
}
